#include "button.h"

void button_task_handler(ButtonObjectTypeDef *self, uint32_t period)
{
    uint32_t pin = self->read_pin(self);

    switch (self->stage)
    {
        case BUTTON_STAGE_NORMAL:
        {
            if (pin == 1)
            {
                self->stage = BUTTON_STAGE_SHAKE;
            }
        }
        break;

        case BUTTON_STAGE_SHAKE:
        {
            if (pin == 1)
            {
                self->stage = BUTTON_STAGE_LONGPRESS;
            }
            else
            {
                self->stage = BUTTON_STAGE_NORMAL;
            }
        }
        break;

        case BUTTON_STAGE_LONGPRESS:
        {
            if (pin == 0)
            {
                self->stage = BUTTON_STAGE_DOUBLEPRESS;
            }
            else
            {
                self->long_ticks_count += period;

                if (self->long_ticks_count >= self->lp_th)
                {
                    self->event_callback(self, BUTTON_EVENT_LONGPRESS);
                    self->stage = BUTTON_STAGE_IDLE;
                }
            }
        }
        break;

        case BUTTON_STAGE_DOUBLEPRESS:
        {
            self->double_ticks_count += period;

            if (pin == 1)
            {
                self->event_callback(self, BUTTON_EVENT_DOUBLE_CLICK);
                self->stage = BUTTON_STAGE_IDLE;
            }
            else if (self->double_ticks_count > self->dp_th)
            {
                self->event_callback(self, BUTTON_EVENT_PRESSED);
                self->stage = BUTTON_STAGE_IDLE;
            }
        }
        break;

        case BUTTON_STAGE_IDLE:
        {
            if (pin == 0)
            {
                self->double_ticks_count = 0;
                self->long_ticks_count = 0;
                self->stage = BUTTON_STAGE_NORMAL;
            }
        }
        break;
    }

}


void button_register_callback(ButtonObjectTypeDef *self, ButtonEventCallbackFuncTypeDef callback)
{
    if (NULL == callback)
    {
        return;
    }

    self->event_callback = callback;
}

void button_defalut_event_callback(ButtonObjectTypeDef *self,  ButtonEventIDEnum event)
{
    while(1);
}

void button_object_init(ButtonObjectTypeDef *self)
{
    self->stage = BUTTON_STAGE_NORMAL;
    self->long_ticks_count = 0;
    self->double_ticks_count = 0;

    /* config */
    self->dp_th = 400;
    self->lp_th = 1500;
    self->event_callback = button_defalut_event_callback;
}

